<template>
    <div id="sysMenuTree" class="sysMenuTree">
        <ul :id="treeId" class="ztree" :class="{'allHeight': config.title==''&&config.addBtn=='', titleHT: config.title!=''||config.addBtn!=''}"></ul>
    </div>
</template>

<script>
    import $ from 'jquery';
    import bus from '@/components/common/js/bus';
    import { fail } from 'assert';
    export default {
        name: 'tree',
        components: {},
        props: {
            treeData: {
                type: Array,
                default () {
                    return []
                }
            },
            config: {
                type: Object,
                default () {
                    return {
                        btns: ['add', 'edit', 'delete'],
                        addBtn: '',
                        title: '',
                        pIdKey: 'pId'
                    }
                }
            }
        },
        data() {
            return {
                treeId: 'treeDemo' + new Date().getTime(),
                setting: {
                    view: {
                        addHoverDom: this.addHoverDom,
                        showIcon: false,
                        showLine: true,
                        selectedMulti: false
                    },
                    edit: {
                        enable: true,
                        showRemoveBtn: this.showRemoveBtn,
                        showRenameBtn: this.showRenameBtn,
                        removeTitle: '删除',
                        renameTitle: '修改',
                        drag: {
                            autoExpandTrigger: true,
                            prev: this.dropPrev,
                            inner: this.dropInner,
                            next: this.dropNext
                        },
                    },

                    data: {
                        simpleData: {
                            enable: true,
                            idKey: "id",
                            pIdKey: this.config.pIdKey,
                            rootPId: 0
                        }
                    },
                    callback: {
                        onClick: this.zTreeOnClick,
                        beforeDrag: this.beforeDrag,
                        beforeDrop: this.beforeDrop,
                        beforeDragOpen: this.beforeDragOpen,
                        onDrag: this.onDrag,
                        onDrop: this.onDrop,
                        onExpand: this.onExpand,
                        beforeEditName: this.beforeEditName,
                        beforeRemove: this.beforeRemove,
                        beforeRename: this.beforeRename,
                        onRemove: this.onRemove,
                    }
                },
                zNodes: [],
                log: '',
                className: 'dark',
                newCount: 1,
                curDragNodes: '',
                autoExpandNode: ''
            }
        },
        watch: {
            treeData(val) {
                $.fn.zTree.init($("#" + this.treeId), this.setting, val);
                this.expandAll();
            },
        },
        mounted() {
            this.$nextTick(() => {
                $.fn.zTree.init($("#" + this.treeId), this.setting, []);
            })
        },
        methods: {
            zTreeOnClick(event, treeId, treeNode) {
                this.$emit('treeNodeClick', treeNode);
            },
            dropPrev(treeId, nodes, targetNode) {
                var pNode = targetNode.getParentNode();
                if (pNode && pNode.dropInner === false) {
                    return false;
                } else {
                    for (var i = 0, l = this.curDragNodes.length; i < l; i++) {
                        var curPNode = this.curDragNodes[i].getParentNode();
                        if (curPNode && curPNode !== targetNode.getParentNode() && curPNode.childOuter === false) {
                            return false;
                        }
                    }
                }
                return true;
            },
            dropInner(treeId, nodes, targetNode) {
                if (targetNode && targetNode.dropInner === false) {
                    return false;
                } else {
                    for (var i = 0, l = this.curDragNodes.length; i < l; i++) {
                        if (!targetNode && this.curDragNodes[i].dropRoot === false) {
                            return false;
                        } else if (this.curDragNodes[i].parentTId && this.curDragNodes[i].getParentNode() !==
                            targetNode && this.curDragNodes[i].getParentNode().childOuter === false) {
                            return false;
                        }
                    }
                }
                return true;
            },
            dropNext(treeId, nodes, targetNode) {
                var pNode = targetNode.getParentNode();
                if (pNode && pNode.dropInner === false) {
                    return false;
                } else {
                    for (var i = 0, l = this.curDragNodes.length; i < l; i++) {
                        var curPNode = this.curDragNodes[i].getParentNode();
                        if (curPNode && curPNode !== targetNode.getParentNode() && curPNode.childOuter === false) {
                            return false;
                        }
                    }
                }
                return true;
            },
            beforeDrag(treeId, treeNodes) {
                this.className = (this.className === "dark" ? "" : "dark");
                this.showLog("[ " + this.getTime() + " beforeDrag ]&nbsp;&nbsp;&nbsp;&nbsp; drag: " + treeNodes.length +
                    " nodes.");
                for (var i = 0, l = treeNodes.length; i < l; i++) {
                    if (treeNodes[i].drag === false) {
                        this.curDragNodes = null;
                        return false;
                    } else if (treeNodes[i].parentTId && treeNodes[i].getParentNode().childDrag === false) {
                        this.curDragNodes = null;
                        return false;
                    }
                }
                this.curDragNodes = treeNodes;
                return true;
            },
            beforeDragOpen(treeId, treeNode) {
                this.autoExpandNode = treeNode;
                return true;
            },
            beforeDrop(treeId, treeNodes, targetNode, moveType, isCopy) {
                // console.log('treeNodes', treeNodes, 'targetNode', targetNode);
                this.className = (this.className === "dark" ? "" : "dark");
                this.showLog("[ " + this.getTime() + " beforeDrop ]&nbsp;&nbsp;&nbsp;&nbsp; moveType:" + moveType);
                this.showLog("target: " + (targetNode ? targetNode.name : "root") + "  -- is " + (isCopy == null ?
                    "cancel" : isCopy ? "copy" : "move"));
                return true;
            },
            onDrag(event, treeId, treeNodes) {
                this.className = (this.className === "dark" ? "" : "dark");
                this.showLog("[ " + this.getTime() + " onDrag ]&nbsp;&nbsp;&nbsp;&nbsp; drag: " + treeNodes.length +
                    " nodes.");
            },
            onDrop(event, treeId, treeNodes, targetNode, moveType, isCopy) {
                this.className = (this.className === "dark" ? "" : "dark");
                this.showLog("[ " + this.getTime() + " onDrop ]&nbsp;&nbsp;&nbsp;&nbsp; moveType:" + moveType);
                this.showLog("target: " + (targetNode ? targetNode.name : "root") + "  -- is " + (isCopy == null ?
                    "cancel" : isCopy ? "copy" : "move"));
            },
            onExpand(event, treeId, treeNode) {
                // console.log('onExpand');
                this.$emit('treeNodeClick', treeNode);
                if (treeNode === this.autoExpandNode) {
                    this.className = (this.className === "dark" ? "" : "dark");
                    this.showLog("[ " + this.getTime() + " onExpand ]&nbsp;&nbsp;&nbsp;&nbsp;" + treeNode.name);
                }
            },
            remove() { // 移除节点
                var zTree = $.fn.zTree.getZTreeObj(this.treeId),
                    nodes = zTree.getSelectedNodes(),
                    treeNode = nodes[0];
                this.$emit("delTreeNode", treeNode)
            },
            beforeRemove(treeId, treeNode) {
                // console.log('remove');
                if (treeNode.id) {
                    this.$emit("delTreeNode", treeNode); // 触发删除
                } else {
                    return true
                }
                return false
            },
            onRemove(e, treeId, treeNode) {
                this.showLog("[ " + this.getTime() + " onRemove ]&nbsp;&nbsp;&nbsp;&nbsp; " + treeNode.name);
            },
            beforeEditName(treeId, treeNode) {
                // console.log('beforeEditName');
                this.$emit('openParaType', treeNode, 'edit');
                return false
            },
            onRename(event, treeId, treeNode, isCancel) {
                // console.log('rename');
                this.$emit("treeInfoEvent", treeNode)
            },
            beforeRename(treeId, treeNode, newName) {
                if (newName.length == 0) {
                    // alert("节点名称不能为空.");
                    this.$alert('节点名称不能为空', '提示', {
                        confirmButtonText: '确定',
                        callback: action => {

                        }
                    });
                    return false;
                } else if (newName.length > 20) {
                    this.$alert('节点名称不能超过20个字', '提示', {
                        confirmButtonText: '确定',
                        callback: action => {

                        }
                    });
                    return false;
                }
                treeNode.name = newName; // 重命名时 新名字替换旧名字
                this.$emit('treeNodeClick', treeNode);
                // console.log('beforeRename-----------重命名时保存'); // 重命名时保存
                return true;
            },
            showLog(str) {
                if (!this.log) this.log = $("#log");
                this.log.append("<li class='" + this.className + "'>" + str + "</li>");
                if (this.log.children("li").length > 8) {
                    this.log.get(0).removeChild(this.log.children("li")[0]);
                }
            },
            getTime() {
                var now = new Date(),
                    h = now.getHours(),
                    m = now.getMinutes(),
                    s = now.getSeconds(),
                    ms = now.getMilliseconds();
                return (h + ":" + m + ":" + s + " " + ms);
            },

            addHoverDom(treeId, treeNode) {
                let _this = this;
                var sObj = $("#" + treeNode.tId + "_span");
                if (treeNode.editNameFlag || $("#addBtn_" + treeNode.tId).length > 0) return;
                var addStr = "<span class='button add' id='addBtn_" + treeNode.tId +
                    "' title='新增' onfocus='this.blur();'></span>";
                sObj.after(addStr);
                var btn = $("#addBtn_" + treeNode.tId);
                if (btn) btn.bind("click", function () {
                    _this.add(treeNode);
                    // console.log('treeNode click plus: ', treeNode);
                    _this.$emit('clickedAddbtnNode', treeNode); // 点击的 添加按钮的node信息 用于保存下级节点
                });
            },
            add(treeNode) { // 增加子节点
                var zTree = $.fn.zTree.getZTreeObj(this.treeId);
                var isParent = false;
                var nodes = zTree.getSelectedNodes();
                var treeNode2 = nodes[0];
                if (treeNode) {
                    treeNode2 = zTree.addNodes(treeNode, {
                        id: "",
                        pId: treeNode.id,
                        sysCode: treeNode.sysCode || treeNode.valStr,
                        isParent: isParent,
                        name: "新子节点" + (this.newCount++)
                    });
                } else {
                    treeNode2 = zTree.addNodes(null, {
                        id: "",
                        pId: 0,
                        isParent: isParent,
                        name: "新节点" + (this.newCount++)
                    });
                }
                if (treeNode2) {
                    zTree.editName(treeNode2[0]);
                } else {
                    alert("叶子节点被锁定，无法增加子节点");
                }
            },
            showRemoveBtn(treeId, treeNode) {
                return treeNode.level >= 1
            },
            showRenameBtn(treeId, treeNode) {
                return false
            },
            expandAll() {
                let zTree = $.fn.zTree.getZTreeObj(this.treeId);
                var nodes = zTree.getNodes();
                if (nodes.length>0) {
                    for(var i=0;i<nodes.length;i++){
                        zTree.expandNode(nodes[0], true, false, false);
                    }
                }
                //if(zTree) zTree.expandAll(false);
            },
        },
    }

</script>
<style lang="scss">
    .sysMenuTree {
        position: relative;
        height: 100%;
        background: #fff;

        .ztree {
            height: calc(100% - 30px);
            overflow: auto;
            padding: 5px;

            li span.button.add {
                background-position: -143px 0;
            }
        }

        .allHeight {
            height: 100% !important;
        }

        .titleHT {
            height: calc(100% - 28px);
        }

        [treenode_a] {
            .button.add {
                margin-right: 2px;
                display: none;
            }

            &:hover {
                .button.add {
                    display: inline-block;
                }
            }

            span {
                vertical-align: middle !important;
            }
        }

        [treenode_a].curSelectedNode {
            .button.add {
                display: inline-block;
            }
        }

        [treenode_switch] {
            vertical-align: middle;
        }
    }

</style>
